package com.restaurant.application.indexes.signinlist.mysql;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.nebutown.base.Unit;
import com.nebutown.description.data.SortSpec;
import com.nebutown.generation.basictype.UID;
import com.nebutown.supporthome.AbstractIndex;

import java.sql.ResultSet;
import java.util.List;
import java.util.Map;

public class SignInListImpl extends AbstractIndex<SignInListCriteria, SignInListBean> {

    @Override
    public String getTableName() {
        return "" + getConnectionName() + ".SIGNINLIST";
    }

    @Override
    public SignInListBean newBean() {
        return new SignInListBean();
    }

    @Override
    public SignInListCriteria newCriteria() {
        return new SignInListCriteria();
    }

    @Override
    public List<String> getFieldNames() {
        return Lists.newArrayList(
                "signInUid",
                "signTime",
                "customerUid",
                "customerName",
                "realName");
    }

    @Override
    public List<String> getDateFields() {
        return Lists.newArrayList(
                "signTime");
    }

    @Override
    public List<String> getDoubleFields() {
        return Lists.newArrayList(
                "");
    }

    @Override
    public Map<String, String> getFieldLabels() {
        return ImmutableMap.<String, String>builder()
                .put("signTime", "签到时间")
                .put("customerName", "客户名")
                .put("realName", "真实姓名")
                .build();
    }

    @Override
    public List<String> getContributors() {
        return Lists.newArrayList(
                "com.restaurant.application.genshanguser.GenShangUser",
                "com.restaurant.application.genshanguser.GenShangUser");
    }

    @Override
    public SignInListBean fakeBean() {
        SignInListBean bean = new SignInListBean();

        bean.setSignInUid(UID.recover("A -5104678985925224710 looooong string"));
        bean.setSignTime(-1881304142L);
        bean.setCustomerUid(UID.recover("A -3973050764622285241 looooong string"));
        bean.setCustomerName("A 4513300300742940946 looooong string");
        bean.setRealName("A 5830014838216431447 looooong string");
        return bean;
    }

    @Override
    public String getCreateTableStatement() {
        StringBuilder buf = new StringBuilder();

        buf.append("CREATE TABLE IF NOT EXISTS " + getConnectionName() + ".SIGNINLIST (\n");
        buf.append("    RECORD_ID BIGINT AUTO_INCREMENT,\n");
        buf.append("    SIGNINUID CHAR(128) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,\n");
        buf.append("    SIGNTIME BIGINT,\n");
        buf.append("    CUSTOMERUID CHAR(128) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,\n");
        buf.append("    CUSTOMERNAME VARCHAR(255),\n");
        buf.append("    REALNAME VARCHAR(255),\n");
        buf.append("PRIMARY KEY (RECORD_ID)) CHARACTER SET  = utf8mb4 COLLATE = utf8mb4_bin");
        return buf.toString();
    }

    @Override
    public String getInsertDataStatement(SignInListBean data) {
        StringBuilder buf = new StringBuilder();

        buf.append("INSERT INTO " + getConnectionName() + ".SIGNINLIST (\n    ");
        buf.append("    SIGNINUID, SIGNTIME, CUSTOMERUID, CUSTOMERNAME, REALNAME");
        buf.append(") VALUES (");
        buf.append("    '" + cut(data.getSignInUid(), 128) + "', " + data.getSignTime() + ", '" + cut(data.getCustomerUid(), 128) + "', '" + cut(data.getCustomerName(), 255) + "', '" + cut(data.getRealName(), 255) + "'");
        buf.append(")");
        return buf.toString();
    }

    @Override
    public String getDeleteRowsStatement(Long rowId) {
        return "DELETE FROM " + getConnectionName() + ".SIGNINLIST WHERE  RECORD_ID = " + rowId;
    }

    @Override
    public String getLocalUpdateStatement(SignInListBean data) {
        StringBuilder buf = new StringBuilder();
        StringBuilder sep = new StringBuilder();

        boolean hasData = false;

        buf.append("UPDATE " + getConnectionName() + ".SIGNINLIST \n");
        buf.append("   SET ");
        if(data.getSignInUid() != null) {
            buf.append(sep.toString() + "\n      SIGNINUID = '" + cut(data.getSignInUid(), 128) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getSignTime() != null) {
            buf.append(sep.toString() + "\n      SIGNTIME = " + data.getSignTime() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerUid() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERUID = '" + cut(data.getCustomerUid(), 128) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerName() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERNAME = '" + cut(data.getCustomerName(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getRealName() != null) {
            buf.append(sep.toString() + "\n      REALNAME = '" + cut(data.getRealName(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(!hasData) return "";

        hasData = false;
        buf.append(" WHERE TRUE\n");
        if(data.getSignInUid() != null) {
            buf.append("    AND SIGNINUID = '" + data.getSignInUid() + "'\n");
            hasData = true;
        }
        if(data.getCustomerUid() != null) {
            buf.append("    AND CUSTOMERUID = '" + data.getCustomerUid() + "'\n");
            hasData = true;
        }
        if(!hasData) return "";

        return buf.toString();
    }

    @Override
    public String getUpdateByIdStatement(SignInListBean data) {
        StringBuilder buf = new StringBuilder();
        StringBuilder sep = new StringBuilder();

        boolean hasData = false;

        buf.append("UPDATE " + getConnectionName() + ".SIGNINLIST \n");
        buf.append("   SET ");
        if(data.getSignInUid() != null) {
            buf.append(sep.toString() + "\n      SIGNINUID = '" + cut(data.getSignInUid(), 128) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getSignTime() != null) {
            buf.append(sep.toString() + "\n      SIGNTIME = " + data.getSignTime() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerUid() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERUID = '" + cut(data.getCustomerUid(), 128) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerName() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERNAME = '" + cut(data.getCustomerName(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getRealName() != null) {
            buf.append(sep.toString() + "\n      REALNAME = '" + cut(data.getRealName(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(!hasData) return "";

        hasData = false;
        buf.append(" WHERE RECORD_ID = " + data.getRecordId());
        return buf.toString();
    }

    @Override
    public SignInListBean extractLine(ResultSet resultSet) throws Exception {
        SignInListBean result = new SignInListBean();

        result.setRecordId(resultSet.getLong("RECORD_ID"));
        result.setSignInUid(UID.recover(resultSet.getString("signInUid")));
        result.setSignTime(resultSet.getLong("signTime"));
        result.setCustomerUid(UID.recover(resultSet.getString("customerUid")));
        result.setCustomerName(resultSet.getString("customerName"));
        result.setRealName(resultSet.getString("realName"));
        return result;
    }

    @Override
    public String getWherePart(SignInListCriteria criteria, SortSpec sort) {
        StringBuilder buf = new StringBuilder(" TRUE ");

        criteria.setCustomerNameLike(searchString(criteria.getCustomerNameLike()));
        criteria.setRealNameLike(searchString(criteria.getRealNameLike()));

        if(criteria.getRecordId() != null) {
            buf.append("    AND RECORD_ID = " + criteria.getRecordId());
        }
        if(criteria.getSignInUidEquals() != null) {
            buf.append("    AND SIGNINUID = '" + criteria.getSignInUidEquals() + "'");
        }
        if(criteria.getSignInUidNotEquals() != null) {
            buf.append("    AND SIGNINUID != '" + criteria.getSignInUidNotEquals() + "'");
        }
        if(criteria.getSignTimeUpper() != null) {
            buf.append("    AND SIGNTIME <= " + criteria.getSignTimeUpper());
        }
        if(criteria.getSignTimeLower() != null) {
            buf.append("    AND SIGNTIME >= " + criteria.getSignTimeLower());
        }
        if(criteria.getSignTimeEquals() != null) {
            buf.append("    AND SIGNTIME = '" + criteria.getSignTimeEquals() + "'");
        }
        if(criteria.getSignTimeNotEquals() != null) {
            buf.append("    AND SIGNTIME != '" + criteria.getSignTimeNotEquals() + "'");
        }
        if(criteria.getCustomerUidEquals() != null) {
            buf.append("    AND CUSTOMERUID = '" + criteria.getCustomerUidEquals() + "'");
        }
        if(criteria.getCustomerUidNotEquals() != null) {
            buf.append("    AND CUSTOMERUID != '" + criteria.getCustomerUidNotEquals() + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getCustomerNameEquals())) {
            buf.append("    AND CUSTOMERNAME = '" + cut(criteria.getCustomerNameEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getCustomerNameNotEquals())) {
            buf.append("    AND CUSTOMERNAME != '" + cut(criteria.getCustomerNameNotEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getCustomerNameLike())) {
            buf.append("    AND CUSTOMERNAME LIKE '" + cut(criteria.getCustomerNameLike()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getRealNameEquals())) {
            buf.append("    AND REALNAME = '" + cut(criteria.getRealNameEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getRealNameNotEquals())) {
            buf.append("    AND REALNAME != '" + cut(criteria.getRealNameNotEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getRealNameLike())) {
            buf.append("    AND REALNAME LIKE '" + cut(criteria.getRealNameLike()) + "'");
        }
        if(sort != null && sort.getColumns().size() > 0) {
            buf.append(" ORDER BY ");
            sort.getColumns().forEach(c->buf.append(c.getColumnName().toUpperCase())
                .append(" ").append((c.getAscending() != null && c.getAscending()) ? "ASC" : "DESC")
                .append(", "));
            buf.append("RECORD_ID ASC");
        }
        return buf.toString();
    }

    @Override
    public <T extends Unit > String getUpdateStatement(T source) {
        SignInListBean data = null;

        if(source instanceof com.restaurant.application.indexes.signinlist.mysql.SignInListFromsignInUidIF) {
            data = new SignInListBean();
             ((com.restaurant.application.indexes.signinlist.mysql.SignInListFromsignInUidIF)source).getSignInUidDataForSignInList(data);
        }
        if(source instanceof com.restaurant.application.indexes.signinlist.mysql.SignInListFromcustomerUidIF) {
            data = new SignInListBean();
             ((com.restaurant.application.indexes.signinlist.mysql.SignInListFromcustomerUidIF)source).getCustomerUidDataForSignInList(data);
        }

        return data == null ? null: getLocalUpdateStatement(data);
    }
}
